/*!
 Temelia - Performance tests common interface for Temelia
 data structures library.

 Copyright (C) 2009 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef PERFORMANCE_COMMON_HPP
#define PERFORMANCE_COMMON_HPP

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <map>
#include <vector>

#define CLUSTER_RUNNING

#define TESTS_NUMBER      (28)
#define MAX_TEST_CHARS    (20)

class TemeliaPerformance
{
public:
	// Maps a string to a test function
	static std::map<std::string, void(*)(void)> string_to_test;
	static std::ofstream *fout;

	// Name convention: PT (performance test) + _ + test name
	static void pt_algorithms(void);
	static void pt_avl(void);
	static void pt_b_tree(void);
	static void pt_binary_search_tree(void);
	static void pt_binary_tree(void);
	static void pt_doubly_linked_list(void);
	static void pt_hash_set(void);
	static void pt_hash_map(void);
	static void pt_heap(void);
	static void pt_interval_tree(void);
	static void pt_linked_list(void);
	static void pt_matrix(void);
	static void pt_graph(void);
	static void pt_pair(void);
	static void pt_queue(void);
	static void pt_red_black_tree(void);
	static void pt_scapegoat_tree(void);
	static void pt_skip_list(void);
	static void pt_sort(void);
	static void pt_sparse_matrix(void);
	static void pt_splay_tree(void);
	static void pt_stack(void);
	static void pt_treap_tree(void);
	static void pt_tree_algorithms(void);
	static void pt_tree(void);
	static void pt_trie(void);
	static void pt_vector(void);

	static char __tests_name[TESTS_NUMBER][MAX_TEST_CHARS];
	static void (*__tests_function[TESTS_NUMBER])(void);

	// Initialize the test internal variables
	static void init();

	// Close the variables; flushes the streams etc.
	static void finish();

	// Runs the test associated with that id
	// The function calls the behavior (pointer to function) associated
	// with the id (test name). The associations are in 'string_to_test'.
	// It does nothing if the test behavior is not defined.
	static void run_test(std::string test);

	/*
	 * The basic structure is:
	 * <data_structure name="data_structure">
	 *   <test_case function="map" library="temelia">
	 *     <test_unit input="1" time="100.000000">
	 *     <test_unit input="10" time="1000.000000">
	 *     <test_unit input="100" time="10000.000000">
	 *     <test_unit input="1000" time="100000.000000">
	 *   </test_case>
	 *   <test_case function="fflush" library="stl">
	 *     <test_unit input="1" time="200.000000">
	 *     <test_unit input="2" time="300.000000">
	 *   </test_case>
	 * </data_structure>
	 */
	// Logs data
	static void my_log(std::string data_structure, std::string function_name,
			std::vector<int> &input_size, std::vector<double> &time,
			std::string library, bool start = false, bool finish = false);
};

int *int_new(int default_value);
void int_delete(void *x, void *context);
void int_handler(void *x, void *context);
void int_level_handler(void *x, int level, void *context);
int int_compare(void *x, void *y, void *context);

int **int_array_new(int size);
void int_array_delete(int **data, int size);

// STL
bool stl_int_compare(int *x, int *y);

// Singleton collection
void init_collection();
void finish_collection();

void exit_with_error(std::string error);

void *my_key_at(void *data, int index);
void my_set_key_at(void *data, int index, void *key);

#endif /* PERFORMANCE_COMMON_HPP */
